home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)graph_scroll.c V1.9 3/13/95";
- #endif
- /*
- | file name - graph_scroll.c
- |===================================================================
- |
- | This example illustrates how to scroll through data for a
- | graph and display the different data sets in the graph. The
- | graph's variable is rebound to a program variable which
- | will hold the value to be displayed in the graph. The values
- | are held in an array which has been initialized to hold
- | 1000 data values. The example defines a tick labeling
- | function in order to label the time axis based on the data
- | elements being displayed. The user selects the starting
- | iteration of data to display using a scrollbar.
- |
- | Typing a <q|Q>, the right mouse button or selecting an object
- | named "quit" will exit the program.
- |
- |===================================================================
- */
- #include <windows.h>
- /*
- * DV-Tools header files
- */
- #include "std.h" /* <stdio.h> etc., scalar & macro definitions */
- #include "dvstd.h" /* public types & constants */
- #include "dvtools.h" /* constants used by T routines */
- #include "dvGR.h" /* constants used by window mgt & GR routines */
- #include "VOstd.h" /* constants used by VO & VOob routines */
- #include "Tfundecl.h" /* T routines (screens, drawports & views) */
- #include "VOfundecl.h" /* VO routines (objects) */
- #include "VUerfundecl.h" /* VUer routines (event handling routines) */
- #include "VPfundecl.h" /* VP routines (put info from dgp & vdp) */
- #include "VGfundecl.h" /* VG routines (get info from dgp & vdp) */
- //#include "GRkeysym.h" /* key symbol definitions */
- #include "math.h" /* math include */
-
- /* Constants */
- #define DVPATH (char *)NULL
- #define DISPFORMS_STB (char *)NULL
- #define DVDEVICE (char *)NULL
- #define DVCOLORTABLE (char *)NULL
- #define VIEW_NAME "graph_scroll.v"
- #define SCREEN_VIEWPORT (RECTANGLE *)NULL
- #define DRAWING_VIEWPORT (RECTANGLE *)NULL
-
- #define SAMPLE_SIZE 50
- #define DATA_SIZE 1000
-
- #define EXPOSE_LABEL 1
- #define RESIZE_LABEL 2
- #define BUTTON_LABEL 3
- #define KEY_LABEL 4
-
- #define LEFT_BUTTON 1
- #define RIGHT_BUTTON 3
- #define SIMPLE_EDGE (OBJECT)1
- #define SCROLLBAR_CLIENT (OBJECT)2
-
- typedef union
- {
- char string[10];
- LABEL_SIZE size;
- } Label_Union;
-
- DRAWPORT drawport; /* how & where to displat picture */
- OBJECT graph; /* graph object */
- DATAGROUP dgp; /* data group pointer */
- double *DataPtr, /* Pointer to data element in array */
- Data[DATA_SIZE]; /* array of data values */
- int Index; /* buffer for scroll bar */
- int Quit = NO; /* flag to quit program */
-
- /* Functions defined in graph_scroll.c */
- int ExposeResizeHandler V_P_((OBJECT scr_client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
- int HandlePressEvent V_P_((OBJECT client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
- int HandleScrollbar V_P_((OBJECT client, EVENT_REQUEST request, int label, OBJECT loc, ADDRESS args));
- ADDRESS RebindVdps V_P_((OBJECT vd_obj, ADDRESS vdp, ADDRESS args));
- void InitData V_P_((void));
- void LabelTimeTics V_P_((ADDRESS args, double *value, ADDRESS output, TIC_DATA * tdp));
-
- /*
- * MAIN PROGRAM
- */
- int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- INT argc = 0;
- CHAR **argv;
-
- /* argv[1] - display device (default is DVDEVICE) */
-
- /* Define & initialize device name and view filename */
- char *device_name = DVDEVICE; /* default device name */
- char *view_name = VIEW_NAME; /* default view name */
-
- /* Define display variables */
- OBJECT screen; /* display device, the window */
- VIEW view; /* picture representation of the view file */
-
- /* Control loop variables */
- OBJECT location; /* the event representation */
-
- /* Other variables */
- OBJECT drawing, /* graphical representation of screen */
- scrollbar; /* scrollbar input object */
- ULONG pick_syms[4]; /* list of valid picks */
-
- argc = 0;
- /*--------------------
- * Initialization
- *
- * TInit: perform the initialization of DV-Tools
- * TInit reads your configuration file and any
- * environment variables or logical names set.
- */
- make_argv(&argc,&argv,GetCommandLine());
- TInit( DVPATH, DISPFORMS_STB );
-
- /*
- * TscOpenSet: open a device as a screen object using
- * specified attributes
- * TscErase: erase the entire screen in the default
- * background color
- *
- * Set exposure block to YES to insure the window
- * is ready for drawing when TdpDraw is called.
- */
- if (argc > 1)
- device_name = argv[1];
- screen = TscOpenSet( device_name, DVCOLORTABLE,
- V_WINDOW_WIDTH, 500,
- V_WINDOW_HEIGHT, 500,
- V_X_EXPOSURE_BLOCK, YES,
- V_ACTIVE_CURSOR, V_END_OF_LIST);
- if (!screen)
- {
- printf ("Must specify device on command line or");
- printf (" in DataViews configuration file.\n");
- S_EXIT (EXIT_ERR);
- }
- TscErase (screen);
-
- /*
- * VOscWinEventMask: sets the screen's window event mask
- */
- VOscWinEventMask ((ULONG) V_KEYPRESS | V_KEYRELEASE |
- V_BUTTONPRESS | V_BUTTONRELEASE |
- V_RESIZE | V_EXPOSE,
- (ULONG) 0);
-
- /*
- * VUerWinEventPost: Posts a request for a window event.
- *
- * Post event requests for "window" events - Expose and Resize.
- */
- VUerWinEventPost (screen, ExposeResizeHandler,
- (ADDRESS) NULL, 0, EXPOSE_LABEL,
- (ULONG) VUER_EXPOSE_EVENT);
- VUerWinEventPost (screen, ExposeResizeHandler,
- (ADDRESS) NULL, 0, RESIZE_LABEL,
- (ULONG) VUER_RESIZE_EVENT);
-
- /*
- * VUerBoundaryEventPost: Posts an event request
- *
- * Post a request for a button event matching the left or right
- * mouse buttons, anywhere on the screen. This is known as a
- * simple edge event.
- */
- pick_syms[0] = (ULONG) LEFT_BUTTON;
- pick_syms[1] = (ULONG) RIGHT_BUTTON;
- pick_syms[2] = V_END_OF_LIST;
- VUerBoundaryEventPost ((OBJECT) SIMPLE_EDGE, HandlePressEvent,
- (ADDRESS) NULL, 0, BUTTON_LABEL,
- (ULONG) VUER_SE_EVENT, V_BUTTONPRESS, pick_syms);
-
- /*
- * Post an event request for a keypress event matching the
- * keys 'q' or 'Q', anywhere on the screen. This is used to
- * quit the program. Key symbols are defined in GRkeysymdef.h.
- */
- pick_syms[0] = 0x071;
- pick_syms[1] = 0x051;
- pick_syms[2] = V_END_OF_LIST;
- VUerBoundaryEventPost ((OBJECT) SIMPLE_EDGE, HandlePressEvent,
- (ADDRESS) NULL, 0, KEY_LABEL,
- (ULONG) VUER_SE_EVENT, V_KEYPRESS, pick_syms);
-
- /*
- * TviLoad: Load a view in from a file,
- * TdpCreate: Create a drawport.
- * The drawport is attached to the screen object
- * specified while view specifies the view to be
- * displayed on the screen.
- */
- view = TviLoad (view_name);
- if (!view)
- {
- printf ("Could not load view from file ");
- printf ("%s.\n", view_name);
- S_EXIT (EXIT_ERR);
- }
- drawport = TdpCreate (screen, view, SCREEN_VIEWPORT, DRAWING_VIEWPORT);
-
- /*
- * TviGetDrawing: Gets a view's drawing object
- * TobForEachVdp: Traverses all variable descriptors
- * in an object
- *
- * Traverse all variable descriptors in the drawing object
- * call the function RebindVdps for each variable descriptor.
- */
- drawing = TviGetDrawing (view);
- TobForEachVdp (drawing, RebindVdps, (ADDRESS) NULL);
-
- /*
- * Initialize internal data buffers.
- */
- Index = 0;
- DataPtr = &Data[0];
-
- /*
- * TdrGetNamedObject: Gets a named object from a drawing.
- * VUerServiceResultPost: Post a service result request.
- *
- * Get the scrollbar input object and post a service result
- * request to monitor input within this object.
- */
- scrollbar = TdrGetNamedObject (drawing, "scrollbar");
- VUerServiceResultPost (SCROLLBAR_CLIENT, HandleScrollbar,
- (ADDRESS) NULL, 0, scrollbar,
- INPUT_DONE | INPUT_ACCEPT, 0);
-
- /*
- * VOdgGetDgp: Returns pointer to data group structure.
- *
- * Get the graph object and it's data group pointer.
- */
- graph = TdrGetNamedObject (drawing, "graph");
- dgp = VOdgGetDgp (graph);
-
- /*
- * VPdgticlabfcn: Assign a tick labeling function to a data
- * group axis.
- *
- * Assign our own tick labeling function to the graph.
- * This is necessary to label the ticks on the horizontal axis
- * correctly when the graph is scrolled.
- */
- VPdgticlabfcn (dgp, V_TIME_AXIS, (DV_TICLABELFUNPTR)LabelTimeTics, (char *) NULL, 0);
-
- /*
- * Initialize the data.
- */
- InitData ();
-
- /*
- * TdpDraw: draw contents of drawport
- */
- TdpDraw (drawport);
-
- /*--------------------
- * Control loop
- *
- * VOloWinEventPoll: Poll for the next window event.
- * Wait until a masked event is generated.
- * VUerHandleLocEvent: Service the event.
- *
- * Poll the event queue for events specified by the window
- * mask. Events will be dispatched to the appropriate
- * handling routines by VUerHandleLocEvent. The event handler,
- * VUerHandleLocEvent will also handle and dispatch events occurring
- * within input objects. Stop when the Quit flag is set to YES.
- */
- FOREVER
- {
- location = VOloWinEventPoll (V_WAIT);
- VUerHandleLocEvent (location);
- if (Quit == YES)
- break;
- }
-
- /*--------------------
- * Termination
- *
- * VUerClearAll: Clears a client's event requests
- * TdpDestroy: Destroy the drawport,
- * TviDestroy: Destroy the view, freeing the allocated memory
- * TscClose: Close the display screen
- * TTerminate: Perform the clean-up for DV-Tools
- */
- VUerClearAll (screen);
- VUerClearAll (SIMPLE_EDGE);
- VUerClearAll (SCROLLBAR_CLIENT);
- TscErase (screen);
- TdpDestroy (drawport);
- TviDestroy (view);
- TscClose (screen);
- TTerminate ();
- return (EXIT_OK);
- }
-
- /*--------------------
- * ExposeResizeHandler -- Service Routine which is called in
- * response to "window" events (Expose and Resize). The
- * event requests that this routine services are posted
- * with VUerWinEventPost (above). The "label" argument
- * tells the routine which request (Expose or Resize)
- * caused the routine to be called.
- */
- /*ARGSUSED*/
- int
- ExposeResizeHandler (scr_client, request, label, loc, args)
- OBJECT scr_client;
- EVENT_REQUEST request;
- int label;
- OBJECT loc;
- ADDRESS args;
- {
- switch (label)
- {
- case EXPOSE_LABEL:
- TscRedraw (scr_client, VOloRegion (loc));
- break;
-
- case RESIZE_LABEL:
- TscReset (scr_client);
- break;
- }
-
- return (int) INPUT_USED;
- }
-
- /*-------------------
- * HandlePressEvent -- Service Routine which is called in response
- * to ButtonPress and KeyPress events in the screen. The event
- * request is posted with VUerBoundaryEventPost. The "label"
- * argument tells the routine which request (ButtonPress or KeyPress)
- * caused the routine to be called. Then, the event is examined
- * to determine if the user has selected to quit the program.
- * The user may quit the program in several manners.
- */
- /*ARGSUSED*/
- int
- HandlePressEvent (client, request, label, loc, args)
- OBJECT client;
- EVENT_REQUEST request;
- int label;
- OBJECT loc;
- ADDRESS args;
- {
- char *obj_name;
-
- switch (label)
- {
- case BUTTON_LABEL:
- switch (VOloButton (loc))
- {
- case LEFT_BUTTON:
- obj_name = TloGetSelectedObjectName (loc);
- if (obj_name)
- if (strcmp (obj_name, "quit") == 0)
- Quit = YES;
- break;
-
- case RIGHT_BUTTON:
- Quit = YES;
- break;
- }
- break;
-
- case KEY_LABEL:
- Quit = YES;
- break;
- }
-
- return (int) INPUT_USED;
- }
-
-
- /*------------------
- * HandleScrollbar -- called when the user uses the scrollbar.
- * Pressing on the scrollbar indicates the user would like
- * to scroll to a different position in the data.
- */
- /*ARGSUSED*/
- int
- HandleScrollbar (client, request, label, loc, args)
- OBJECT client;
- EVENT_REQUEST request;
- int label;
- OBJECT loc;
- ADDRESS args;
- {
- float start;
-
- /* Make sure the user does not scroll off the end of the data */
- if (Index > (DATA_SIZE - SAMPLE_SIZE))
- Index = DATA_SIZE - SAMPLE_SIZE;
-
- /*
- * Set DataPtr (the variable to which the graph's vdp is rebound) to
- * point to the appropriate location in the data array.
- */
- DataPtr = &Data[Index];
-
- /*
- * VPdgtime_start_incr: Sets the start and increment values of
- * the time axis.
- * TdpDrawObject: Draw an object to the drawport
- *
- * Set the "start" time value for the graph, this will be
- * passed to the tick labeling function to generate
- * appropriate tick labels.
- */
- start = (float) Index;
- VPdgtime_start_incr (dgp, &start, (float *) NULL);
- VPdgdfreset (dgp);
- TdpDrawObject (drawport, graph);
-
- return (int)INPUT_USED;
- }
-
- /*-------------
- * RebindVdps -- modify the variable descriptor to use our own
- * program variable as the memory buffer. The variable
- * descriptor which had previously pointed to a data source
- * variable for the data will now look at our program variable
- * for the data information.
- */
- /*ARGSUSED*/
- ADDRESS
- RebindVdps (vd_obj, vdp, args)
- OBJECT vd_obj;
- ADDRESS vdp;
- ADDRESS args;
- {
- char *name; /* variable descriptor name */
-
- /*
- * VGvdvarname: Gets a pointer to the variable name
- *
- * The name of the variable descriptor is used to
- * determine which buffer to rebind to. If the
- * variable does not have a name then return.
- */
- name = VGvdvarname (vdp);
- if (!name)
- return V_CONTINUE_TRAVERSAL;
-
- /*
- * TvdPutBuffer: Sets a new variable descriptor buffer
- *
- * Rebind vdp to internal program variable.
- */
- if (S_STRCMP (name, "Index") == 0)
- TvdPutBuffer (vdp, (ADDRESS) & Index);
- else if (strcmp (name, "Data") == 0)
- {
- TvdPutBuffer (vdp, (ADDRESS) & DataPtr);
-
- /*
- * VPvd_accmode: Set the data access mode to direct or indirect.
- *
- * Set the "access mode" of the vdp named Data to INDIRECT.
- * This means the variable DataPtr contains the address of
- * the data, not the actual data.
- */
- VPvd_accmode (vdp, V_INDIR_ACCESS);
- }
-
- return V_CONTINUE_TRAVERSAL;
- }
-
-
- /*-----------
- * InitData -- initialize the Data array to "interesting" values.
- * This way we can tell visually if the graph is scrolling.
- * In a real application, Data would contain your historical data.
- */
- void InitData ()
- {
- double scale, sin_val;
- int i;
-
- for (i = 0; i < DATA_SIZE; i++)
- {
- scale = (double) i / (double)DATA_SIZE;
- sin_val = sin ((double) i / (double)3.0);
- Data[i] = sin_val * scale;
- }
- }
-
- /*----------------
- * LabelTimeTics -- the tic label function for the graph.
- */
- /*ARGSUSED*/
- void
- LabelTimeTics (args, value, output, tdp)
- ADDRESS args;
- double *value;
- ADDRESS output;
- TIC_DATA *tdp;
- {
- Label_Union *label_output = (Label_Union *)output;
-
- /*
- * "value" represents the value associated with the tick mark.
- *
- * If "value" is NULL, "label_output" points to a LABEL_SIZE structure which
- * receives the size of the text string. If "value" is non-NULL then
- * label_output is a pointer to a string array which receives the tick
- * label generated for this "value".
- */
- if (value == (double *) NULL)
- {
- label_output->size.StringLength = 9;
- label_output->size.NumLines = 2;
- label_output->size.LongestLine = 5;
- }
- else
- sprintf (label_output->string, "Index\n%d", (int) * value);
- }
-
-
-
-